
require "LevelHelper.Helpers.LHHelpers"
require "LevelHelper.Helpers.LHObject"
require "LevelHelper.Helpers.LHArray"
require "LevelHelper.Helpers.LHDictionary"

require "LevelHelper.Nodes.LHBatch"
require "LevelHelper.Nodes.LHSprite" ;
require "LevelHelper.Nodes.LHBezier" ;

local lh_untitledLayersCount = 0;

LHLayer = Core.class(Sprite)
function LHLayer:layerWithDictionary(dictionary)
    
    if (nil == dictionary) then
        print("Invalid LHLayer initialization! - dictionary is nil")
    end
            
    --add all LevelHelper valid properties to the object
    self.lhNodeType = "LHLayer";
    self.lhIsMainLayer = false;
    self.lhParentLoader= nil; -- just as a reminder that this property exist
                        
    uName = dictionary:stringForKey("UniqueName");
    if(uName)then
       self.lhUniqueName = uName;
    else 
       self.lhUniqueName = "UntitledLayer_" .. lh_untitledLayersCount;
       lh_untitledLayersCount = lh_untitledLayersCount + 1;
    end
                
    self.lhZOrder = dictionary:intForKey("ZOrder")
    
    self:setUserClassProperties(dictionary);
      
    local childsInfo = dictionary:objectForKey("Children");
    if(childsInfo~=nil)then
        local childrenInfo = childsInfo:arrayValue();
        if(childrenInfo ~=nil)then
            for i=1, childrenInfo:count() do    
                local dict = childrenInfo:dictAtIndex(i);
                
                --dict:print();
                
                self:addLayerChildFromDictionary(dict);
            end
        end
    end
        
    
    return self
end
--------------------------------------------------------------------------------
function LHLayer:userCustomInfoClassName()
    return self.lhClassName   
end
--------------------------------------------------------------------------------
function LHLayer:userCustomInfo()
     return self.lhUserCustomInfo;
end
--------------------------------------------------------------------------------
function LHLayer:addLayerChildFromDictionary(childDict)

    --print("ADD LAYER CHILD FROM DICT");
    if(nil == childDict)then
        return
    end
    
    nodeType = childDict:stringForKey("NodeType");
        
    if(nodeType == "LHBatch")then
        
        local batch = LHBatch.new();
           batch:batchWithDictionary(childDict);
        
           self:addChild(batch, batch.lhZOrder);
           batch.lhParentLoader = self.lhParentLoader;
           
    elseif(nodeType == "LHSprite")then
        local spr = LHSprite.new();
        spr:spriteWithDictionary(childDict);
        if(spr ~= nil)then
            self:addChild(spr, spr.lhZOrder);
            spr.lhParentLoader = self.lhParentLoader;        
        end
    elseif(nodeType == "LHBezier")then
        local bez = LHBezier.new();
        bez:bezierWithDictionary(childDict);
        if(bez ~= nil)then
            self:addChild(bez, bez.lhZOrder)
            bez.lhParentLoader = self.lhParentLoader
        end
    elseif(nodeType == "LHLayer")then
        local newLayer = layerWithDictionary(childDict)
        self:addChild(newLayer, newLayer.lhZOrder);
        newLayer.lhParentLoader = self.lhParentLoader;
    end
    
    nodeType = nil
end
--------------------------------------------------------------------------------
function LHLayer:uniqueName()
    return self.lhUniqueName;
end
--------------------------------------------------------------------------------
function LHLayer:isMainLayer()
    return self.lhIsMainLayer;
end
--------------------------------------------------------------------------------
function LHLayer:removeSelf() --this will also remove all children

    --print("calling LHLayer remove self " .. self.lhUniqueName .. " children " .. tostring(self.numChildren));

     --we use while because if we use for - when removing object we may lose some other objects that now have a lower index
    while(self:getNumChildren() ~= 0) do
        local node = self:getChildAt(1)
        if(node)then
            node:removeSelf()
        end
        node = nil;
    end

       self:removeFromParent();
end
--------------------------------------------------------------------------------
function LHLayer:layerWithUniqueName(name) --returns LHLayer with name, does not return self (group)

    for i = 1, self:getNumChildren() do

        local node = self:getChildAt(i)
            
        if(nil ~= node and node.lhNodeType ~= nil)then    
            if(node.lhNodeType == "LHLayer")then
    
                if(node.lhUniqueName == name)then
                    return node;        
                else
                    local layer = node:layerWithUniqueName(name)
                    if(layer ~= nil)then
                        return layer;
                    end
                end
            end            
        end
    end
    return nil;
end
--------------------------------------------------------------------------------
function LHLayer:batchWithUniqueName(name)--returns LHBatch with name (group)
    for i = 1, self:getNumChildren() do

        local node = self:getChildAt(i)
            
        if(nil ~= node and node.lhNodeType ~= nil)then    
            if(node.lhNodeType == "LHBatch")then
            
                if(node.lhUniqueName == name)then
                    return node;        
                end
            
            elseif(node.lhNodeType == "LHLayer")then
            
                local child = node:batchWithUniqueName(name)
                if(child~= nil)then
                    return child;
                end
            end
        end
    end
    
    return nil;
end
--------------------------------------------------------------------------------
function LHLayer:spriteWithUniqueName(name)--returns LHSprite with name (displayObject)

    for i = 1, self:getNumChildren()  do

        local node = self:getChildAt(i)
            
        if(nil ~= node and node.lhNodeType ~= nil)then    
            if(node.lhNodeType == "LHSprite")then
                if(node.lhUniqueName == name)then
                    return node;
                end
            elseif(node.lhNodeType == "LHBatch")then
                local child = node:spriteWithUniqueName(name)
                if(child)then
                    return child;        
                end
            elseif(node.lhNodeType == "LHLayer")then
                local child = node:spriteWithUniqueName(name)
                if(child)then
                    return child;
                end
            end
        end
    end
    
    return nil;
end
--------------------------------------------------------------------------------
function LHLayer:bezierWithUniqueName(name)--returns LHBezier with name
        
    for i = 1, self:getNumChildren() do
        local node = self:getChildAt(i)
        if(nil ~= node and node.lhNodeType ~= nil)then    
            if(node.lhNodeType == "LHBezier")then
                if(node.lhUniqueName == name)then
                    return node;
                end
            elseif(node.lhNodeType == "LHLayer")then
                local child = node:bezierWithUniqueName(name)
                if(child)then
                    return child;
                end
            end
        end
    end
    
    return nil;
end
--------------------------------------------------------------------------------
function LHLayer:allLayers() --returns array with all LHLayer objects, does not return self
    --does not return self
    
    local tempTable = {}
    for i = 1, self:getNumChildren() do
        local obj = self:getChildAt(i)
        
        if(obj and obj.lhNodeType and obj.lhNodeType == "LHLayer")then
            tempTable[#tempTable+1] = obj;
        end
    end
    
    return tempTable;
end
--------------------------------------------------------------------------------
function LHLayer:allBatches() --returns array with LHBatch objects

    local tempTable = {}
    for i = 1, self:getNumChildren() do
        local obj = self:getChildAt(i)
        
        if(obj and obj.lhNodeType and obj.lhNodeType == "LHBatch")then
            tempTable[#tempTable+1] = obj;
        end
    end
    
    return tempTable;
end
--------------------------------------------------------------------------------
function LHLayer:allSprites()--returns array with LHSprite objects
    local tempTable = {}
    for i = 1, self:getNumChildren() do
        local obj = self:getChildAt(i)
        
        if(obj and obj.lhNodeType and obj.lhNodeType == "LHSprite")then
            tempTable[#tempTable+1] = obj;
        end
        
        if(obj and obj.lhNodeType and obj.lhNodeType == "LHBatch")then
            local batchSprites = obj:allSprites()
            for j = 1, #batchSprites do
                tempTable[#tempTable+1] = batchSprites[j];                
            end
        end

        if(obj and obj.lhNodeType and obj.lhNodeType == "LHBayer")then
            local layerSprites = obj:allSprites()
            for j = 1, #layerSprites do
                tempTable[#tempTable+1] = layerSprites[j];                
            end
        end
    end
    
    return tempTable;
end
--------------------------------------------------------------------------------
function LHLayer:allBeziers()--returns array with LHBezier objects
    local tempTable = {}
    for i = 1, self:getNumChildren() do
        local obj = self:getChildAt(i)
        
        if(obj and obj.lhNodeType and obj.lhNodeType == "LHBezier")then
            tempTable[#tempTable+1] = obj;
        end
    end
    
    return tempTable;
end
--------------------------------------------------------------------------------
function LHLayer:layersWithTag(tag) --returns array with LHLayer objects with tag, does not return self
    local tempTable = {}
    for i = 1, self:getNumChildren() do
        local obj = self:getChildAt(i)
        
        if(obj and obj.lhNodeType and obj.lhNodeType == "LHLayer")then
            if(obj.lhTag and obj.lhTag == tag)then
                tempTable[#tempTable+1] = obj;
            end
        end
    end
    
    return tempTable;
end
--------------------------------------------------------------------------------
function LHLayer:batchesWithTag(tag) --returns array with LHBatch objects with tag
    local tempTable = {}
    for i = 1, self:getNumChildren() do
        local obj = self:getChildAt(i)
        
        if(obj and obj.lhNodeType and obj.lhNodeType == "LHBatch")then
            if(obj.lhTag and obj.lhTag == tag)then
                tempTable[#tempTable+1] = obj;
            end
        end
    end
    
    return tempTable;
end
--------------------------------------------------------------------------------
function LHLayer:spritesWithTag(tag) --returns array with LHSprite objects with tag
    local tempTable = {}
    
    for i = 1, self:getNumChildren() do
        local obj = self:getChildAt(i)
        
        if(obj and obj.lhNodeType and obj.lhNodeType == "LHBatch")then
            local otherTable = obj:spritesWithTag(tag);
            for j = 1, #otherTable do
                tempTable[#tempTable+1] = otherTable[j];
            end
        end
        
        if(obj and obj.lhNodeType and obj.lhNodeType == "LHSprite")then
            if(obj.lhTag and obj.lhTag == tag)then
                tempTable[#tempTable+1] = obj;
            end
        end

    end
    
    return tempTable;
end
--------------------------------------------------------------------------------
function LHLayer:beziersWithTag(tag) --returns array with LHBezier objects with tag
    local tempTable = {}
    for i = 1, self:getNumChildren() do
        local obj = self:getChildAt(i)
        
        if(obj and obj.lhNodeType and obj.lhNodeType == "LHBezier")then
            if(obj.lhTag and obj.lhTag == tag)then
                tempTable[#tempTable+1] = obj;
            end
        end
    end
    
    return tempTable;
end
--------------------------------------------------------------------------------
function LHLayer:setUserClassProperties(spriteInfo)

    local classInfo = spriteInfo:dictForKey("CustomClassInfo");

    if(nil == classInfo)then
        return
    end
    
    self.lhClassName = classInfo:stringForKey("ClassName");
    
    if(self.lhClassName == nil)then
        return
    end
    
    require("LevelHelper.CustomClasses.LHCustomClasses");
    self.lhUserCustomInfo = lh_customClassInstanceWithName(self.lhClassName);

    if(self.lhUserCustomInfo == nil)then
        return
    end
    
    local classRep = classInfo:dictForKey("ClassRepresentation");
    
    self.lhUserCustomInfo:setPropertiesFromDictionary(classRep);
end
--------------------------------------------------------------------------------
